﻿#include "ssDateTimer.h"
#include "../ssTime.h"

namespace StarSeeker
{

ssDateTimer::ssDateTimer()
:m_msgHeap(true)
{
	m_ids.Init(1, 4000000000);
}

ssDateTimer::~ssDateTimer()
{
}

u32 ssDateTimer::AddTimer(u32 msgType, u64 timestamp, u32 interval, ulint p1, ulint p2)
{
	ssTimer_s msg;
	msg.msgID = msgType;
	msg.timestamp = timestamp;
	msg.interval = interval;
	msg.param[0] = p1;
	msg.param[1] = p2;
	msg.subID = m_ids.GetID();
	m_msgHeap.Push(msg);
	return msg.subID;
}

u32 ssDateTimer::AddTimer(u32 msgType, u32 interval, ulint param1, ulint param2)
{
	return AddTimer(msgType, ssTime::GetTimeNow().u64p, interval, param1, param2);
}

void ssDateTimer::StartHalfTimer()
{
	u64 now = ssTime::GetTimeNow().u64p;
	u64 beg = 1800 - now % 1800;
	AddTimer(SS_TIMER_HALF_HOUR, now + beg, 0, 0, 0);
}

void ssDateTimer::RemoveTimer(u32 timerId)
{
	ssArray<ssTimer_s>& a = SS_CONST_CAST(ssArray<ssTimer_s>&, m_msgHeap.Array());
	for (ulint i = 0; i < a.Count(); ++i)
	{
		if (a[i].subID == timerId)
		{
			a[i].msgID = SS_TIMER_DEL;
			break;
		}
	}
}

StarSeeker::ulint ssDateTimer::GetTimerCount()
{
	return m_msgHeap.Count();
}

void ssDateTimer::Update(u64 nowTimestamp)
{
	if (m_msgHeap.Count()>0)
	{
		ssTimer_s top = m_msgHeap.Top();
		if (nowTimestamp > top.timestamp)
		{
			m_msgHeap.Pop();
			switch (top.msgID)
			{
			case SS_TIMER_ONCE://单次计时器
			{
				//Dispatch(top.msgID, top.subID, top.param[0], top.param[1]);
				OnTimerOnce(top.subID, top.param[0], top.param[1]);
			}
			break;
			case SS_TIMER_REPEAT://重复计时器
			{
				//Dispatch(top.msgID, top.subID, top.param[0], top.param[1]);
				OnTimerRepeat(top.subID, top.param[0], top.param[1]);
				top.timestamp = nowTimestamp + top.interval;
				m_msgHeap.Push(top);
			}
			break;
			case SS_TIMER_HALF_HOUR://半点计时器
			{
				//Dispatch(top.msgID, top.subID, top.param[0], top.param[1]);
				OnTimerHalfHour(top.subID, top.param[0], top.param[1]);
				u64 beg = 1800 - nowTimestamp % 1800;
				top.timestamp = nowTimestamp + beg;
				m_msgHeap.Push(top);
			}
			break;
			default:
				break;
			}
		}
	}
}

}
